/**
 * pharma-process - 1 juin 2011
 * guillaume
 */
package org.bspv.pharma.process.impl;

import java.util.List;

import org.bspv.pharma.business.OrderManagementBusinessService;
import org.bspv.pharma.business.SecurityBusinessService;
import org.bspv.pharma.business.SupplyManagementBusinessService;
import org.bspv.pharma.common.exception.EntityNotFoundException;
import org.bspv.pharma.common.exception.ViolatedBusinessRuleException;
import org.bspv.pharma.model.Drugstore;
import org.bspv.pharma.model.Order;
import org.bspv.pharma.model.Order.OrderStateEnum;
import org.bspv.pharma.model.OrderDetail;
import org.bspv.pharma.model.TypeOfSupply;
import org.bspv.pharma.model.User;
import org.bspv.pharma.process.ManagementProcessService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author guillaume
 *
 */
@Service(value="managementProcessService")
@Transactional(propagation = Propagation.REQUIRED)
public class ManagementProcessServiceImpl implements ManagementProcessService {
    
    /**
     * Logger.
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(ManagementProcessServiceImpl.class);
    
    /**
     * Service métier de gestion des commandes.
     */
    @Autowired
    private OrderManagementBusinessService orderManagementBusinessService;
    /**
     * Service métier de gestion des fournitures.
     */
    @Autowired
    private SupplyManagementBusinessService supplyManagementBusinessService;
    
    /**
     * Service métier de gestion des utilisateurs.
     */
    @Autowired
    private SecurityBusinessService securityBusinessService;

    
    /**
     * {@inheritDoc}
     */
    @Override
    public void deleteOrderById(Long orderId, String comment, Long userId) throws EntityNotFoundException, ViolatedBusinessRuleException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        User user = securityBusinessService.findUserById(userId);
        if (user == null) {
            LOGGER.error("L'utilisateur {} est inexistant", userId);
            throw new EntityNotFoundException("Utilisateur inexistant");
        }
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        orderManagementBusinessService.deleteOrder(order, comment, user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void cancelOrderById(Long orderId, String comment, Long userId) throws EntityNotFoundException,
            ViolatedBusinessRuleException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        User user = securityBusinessService.findUserById(userId);
        if (user == null) {
            LOGGER.error("L'utilisateur {} est inexistant", userId);
            throw new EntityNotFoundException("Utilisateur inexistant");
        }
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        orderManagementBusinessService.cancelOrder(order, comment, user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sendOrderById(Long orderId, String comment, Long userId) throws EntityNotFoundException,
            ViolatedBusinessRuleException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        User user = securityBusinessService.findUserById(userId);
        if (user == null) {
            LOGGER.error("L'utilisateur {} est inexistant", userId);
            throw new EntityNotFoundException("Utilisateur inexistant");
        }
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        orderManagementBusinessService.sendOrder(order, comment, user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void beginOrderDelivery(Long orderId, String comment, Long userId) throws EntityNotFoundException,
            ViolatedBusinessRuleException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        User user = securityBusinessService.findUserById(userId);
        if (user == null) {
            LOGGER.error("L'utilisateur {} est inexistant", userId);
            throw new EntityNotFoundException("Utilisateur inexistant");
        }
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        orderManagementBusinessService.beginOrderDelivery(order, comment, user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void completeOrderDelivery(Long orderId, String comment, Long userId) throws EntityNotFoundException,
            ViolatedBusinessRuleException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        User user = securityBusinessService.findUserById(userId);
        if (user == null) {
            LOGGER.error("L'utilisateur {} est inexistant", userId);
            throw new EntityNotFoundException("Utilisateur inexistant");
        }
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        orderManagementBusinessService.completeOrderDelivery(order, comment, user);
    }

    /**
     * {@inheritDoc}
     * 
     */
    @Override
    public Order createOrder(Long drugstoreId, String orderComment, String orderDescription, String comment, Long userId) throws ViolatedBusinessRuleException, EntityNotFoundException {
        Order order = new Order();
        Drugstore drugstore = null; //TODO Récupération de la pharmacie à partir de l'identifiant en paramètre
        User user = securityBusinessService.findUserById(userId);
        if (user == null) {
            LOGGER.error("L'utilisateur {} est inexistant", userId);
            throw new EntityNotFoundException("Utilisateur inexistant");
        }
        order.setDrugstore(drugstore);
        order.setComment(orderComment);
        order.setDescription(orderDescription);
        order.setState(OrderStateEnum.ENCOURS);
        return orderManagementBusinessService.createOrder(order, comment, user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateOrderDetail(Long orderId, Long typeOfSupplyId, Integer quantity) throws EntityNotFoundException,
            ViolatedBusinessRuleException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        TypeOfSupply typeOfSupply = supplyManagementBusinessService.findTypeOfSupply(typeOfSupplyId);
        if (typeOfSupply == null) {
            LOGGER.error("Le type de fourniture {} est inexistant", typeOfSupplyId);
            throw new EntityNotFoundException("Type de fourniture inexistant");
        }
        orderManagementBusinessService.updateOrderDetail(order, typeOfSupply, quantity);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<OrderDetail> findOrderDetails(Long orderId) throws EntityNotFoundException {
        Order order = orderManagementBusinessService.findOrder(orderId);
        if (order == null) {
            LOGGER.error("La commande {} est inexistante", orderId);
            throw new EntityNotFoundException("Commande inexistante");
        }
        return orderManagementBusinessService.findOrderDetails(order);
    }

}
